import type { OptionsConfig } from '../../lib/abstract'
import type { PageType } from '../../lib/page_handler/type'
import type { PlatformTypeValue } from '../../types/interfaces'
import type { ModuleManager } from '../module_manager'
import type {
  FeatureConfig,
  FeatureHandler,
  FeatureItem,
  ModuleId,
  ModulePlatformConfig,
  SetFeatureEnabledOptions,
} from './types'
import { detectElementHideRules } from '../../element/service'
import { BaseModule } from '../../lib/abstract'
import { PageHandler } from '../../lib/page_handler'
import { ToolKit } from '../../lib/utils/toolkit'
import {
  getPlatformValue,
  HOSTNAME,
  logger,
  loggerDeduplicator,
  SUPPORTED_PLATFORMS,
} from '../../types/constants'
import { EffectType, SYMBOLS } from '../../types/interfaces'
import { getAppearanceModules } from './configs/appearance'
import { getContentModules } from './configs/content'
import { getDataPresentationModules } from './configs/data_presentation'
import { getInteractionModules } from './configs/interaction'
import { getNavigationModules } from './configs/navigation'
import { getGreasyForkModules } from './configs/platforms/greasyfork'
import { AppModule } from './types'
import { getModuleLatestVersion } from './versions'

interface Config {
  enabled?: boolean
}

const defaultVersion = '1.0.0'

/**
 * 配置管理器（单例模式）
 */
export class ConfigManager extends BaseModule {
  readonly id: string = 'config_manager'
  readonly name: string = 'ConfigManager'
  readonly isInitialized: boolean = false
  readonly supportedPlatforms?: string[] | undefined
  private static instance: ConfigManager
  private modulePlatformConfig: ModulePlatformConfig // 模块与平台关系
  featureHandlers: Map<ModuleId, FeatureHandler> = new Map()
  // 存储配置
  featureStoragePrefix: string = 'feature:'
  storageOptions: OptionsConfig = { useNamespace: false }
  // 页面配置
  private lastPageType: PageType | undefined
  get pageType(): PageType {
    const currentPageType = PageHandler.detectCurrentPageType()
    this.handlePageTypeChange(currentPageType)
    return currentPageType
  }

  constructor() {
    super()

    const pageType = this.pageType

    this.modulePlatformConfig = this.getModulePlatformConfig(pageType)
    this.lastPageType = pageType
  }

  config: Config = {
    enabled: true,
  }

  init(): Promise<void> | void {
    this.core()
  }

  destroy(): Promise<void> | void {
  }

  core(): Promise<void> | void {
  }

  onToggleCallback(_id: string, _checked: boolean): Promise<void> | void {
  }

  /**
   * 获取单例实例
   */
  static getInstance(): ConfigManager {
    if (!ConfigManager.instance) {
      ConfigManager.instance = new ConfigManager()
    }
    return ConfigManager.instance
  }

  /**
   * 处理页面类型变化
   */
  handlePageTypeChange(pageType: PageType): void {
    if (!this.lastPageType || this.lastPageType === pageType)
      return

    this.lastPageType = pageType
    this.modulePlatformConfig = this.getModulePlatformConfig(pageType)

    logger.info(`[${this.name}] 更新模块平台关系配置（${pageType}）`)
  }

  /**
   * 获取模块与平台关系配置
   */
  getModulePlatformConfig(pageType: PageType): ModulePlatformConfig {
    return {
      ...getNavigationModules(pageType),
      ...getAppearanceModules(pageType),
      ...getContentModules(pageType),
      ...getInteractionModules(pageType),
      ...getDataPresentationModules(pageType),
      ...getGreasyForkModules(pageType),
    }
  }

  /**
   * 获取模块对应的功能 ID 值
   * @param moduleName 模块名称
   */
  getFeatureIdValueForModule(moduleName: string): ModuleId {
    return Object.values(AppModule)
      ?.find(meta => meta.className === moduleName)
      ?.id || ''
  }

  /**
   * 获取功能的生效类型
   */
  getFeatureEffectType(featureId: ModuleId): EffectType {
    return this.getFeatureConfig(HOSTNAME, featureId).effectType as EffectType
  }

  /**
   * 获取功能在指定平台的配置（合并默认值和平台特定配置）
   * @param hostname 平台域名
   * @param featureId 功能 ID
   */
  getFeatureConfig(hostname: string, featureId: ModuleId): FeatureConfig {
    const feature = this.modulePlatformConfig[featureId]

    if (!feature)
      return {} as FeatureConfig

    // 获取平台特定配置（可能为undefined）
    const platformValue = getPlatformValue(hostname)
    const platformConfig = platformValue ? feature.supportedPlatforms?.[platformValue] : {}

    // 合并配置（平台配置覆盖默认 meta 配置）
    return {
      ...feature.meta,
      ...platformConfig,
    }
  }

  /**
   * 判断功能是否在平台可用
   * @param config 功能配置
   */
  judgeIsSupported(config: FeatureConfig): boolean {
    // 基础平台支持状态检查
    const platformSupported = ['supported', 'experimental'].includes(config.status || 'not-supported')
    // 检查页面类型验证器
    const pageValid = config.pageTypeValidator ? config.pageTypeValidator() : true

    return platformSupported && pageValid
  }

  /**
   * 检查功能是否在平台可用
   * @param hostname 平台域名
   * @param featureId 功能ID
   */
  isFeatureSupported(hostname: string, featureId: ModuleId): boolean {
    const config = this.getFeatureConfig(hostname, featureId)
    return this.judgeIsSupported(config)
  }

  /**
   * 获取模块支持的平台域名列表
   * @param moduleName 模块名称
   * @returns 支持平台域名列表
   */
  moduleSupportedPlatforms(moduleName: string): string[] {
    const featureId = this.getFeatureIdValueForModule(moduleName)
    if (!featureId) {
      logger.error(`[${this.name}] 未找到模块名称 ${moduleName} 对应的功能 ID`)
      return []
    }

    const feature = this.modulePlatformConfig[featureId]
    if (!feature) {
      logger.error(`[${this.name}] 未找到功能 ID ${featureId} 对应的模块配置`)
      return []
    }

    // 1. 获取默认支持状态
    const defaultSupport = this.judgeIsSupported(feature.meta)

    // 2. 如果没有平台特定配置，返回全部或空数组
    if (!feature.supportedPlatforms) {
      return defaultSupport ? Object.values(SUPPORTED_PLATFORMS) : []
    }

    // 3. 获取明确配置支持的平台
    const explicitlySupportedPlatforms = Object.entries(feature.supportedPlatforms)
      .filter(() => this.isFeatureSupported(HOSTNAME, featureId))
      .map(([hostname]) => hostname)

    // 4. 合并结果（如果默认支持则包含所有平台，然后过滤掉明确不支持的）
    // 平台列表
    const allSupportedPlatforms: string[] = Object.values(SUPPORTED_PLATFORMS)
    const allPlatforms: string[] = defaultSupport
      ? allSupportedPlatforms.filter((hostname: PlatformTypeValue) => {
          const platformConfig = feature.supportedPlatforms?.[hostname]
          // 保留没有配置或明确支持的平台
          return !platformConfig || this.judgeIsSupported(platformConfig)
        })
      : []

    // 合并并去重
    return [...new Set([...allPlatforms, ...explicitlySupportedPlatforms])].sort((a: PlatformTypeValue, b: PlatformTypeValue) => a.localeCompare(b))
  }

  /**
   * 获取平台定制描述
   * @param hostname 平台域名
   * @param featureId 功能 ID
   */
  getCustomDescription(hostname: string, featureId: string): string | undefined {
    const feature = this.modulePlatformConfig[featureId]
    if (!feature)
      return undefined

    const supportedPlatforms = feature.supportedPlatforms
    if (!supportedPlatforms)
      return undefined

    const platformValue = getPlatformValue(hostname)
    const platformConfig = platformValue ? supportedPlatforms[platformValue] : undefined

    if (!platformConfig)
      return undefined

    const description = platformConfig.description

    if (typeof description === 'function')
      return description()

    return description
  }

  /**
   * 获取增强后的功能配置（合并元数据和平台配置）
   * @param hostname 平台域名
   * @param featureId 功能 ID
   */
  getEnhancedFeatureConfig(hostname: string, featureId: ModuleId): FeatureItem | undefined {
    const feature = this.modulePlatformConfig[featureId]
    if (!feature)
      return undefined

    const config = this.getFeatureConfig(hostname, featureId)
    const customDesc = this.getCustomDescription(hostname, featureId)
    const { version, releaseDate, changelog } = getModuleLatestVersion(featureId) || {}

    let description = customDesc || feature.meta.description
    const loginRequired = config.loginRequired ?? false
    const isLoggedIn = ToolKit.browser.platform.isLoggedIn()

    if (loginRequired) {
      description = `${description}（登录后才能使用）`
    }

    // 合并配置（平台配置覆盖默认 meta 配置）
    return {
      enabled: this.getFeatureEnabled(featureId),
      id: featureId,
      name: config.name || feature.meta.name,
      description,
      isCustomDescription: !!customDesc,
      category: config.category || feature.meta.category,
      defaultEnabled: config.defaultEnabled ?? false,
      effectType: config.effectType ?? EffectType.MIXED,
      icon: config.icon || feature.meta.icon,
      dependencies: config.dependencies,
      status: config.status || 'not-supported',
      show: (config.show || feature.meta.show) ?? true,
      version: version || defaultVersion,
      releaseDate: releaseDate || '',
      changelog,
      usePageTypeIsolation: (config.usePageTypeIsolation || feature.meta.usePageTypeIsolation) ?? false,
      loginRequired,
      isLoggedIn,
    }
  }

  /**
   * 获取平台支持的模块列表
   */
  getPlatformModules(): FeatureItem[] {
    const modules = Object.values(AppModule).map(module => module.className)
    const supportedModules: FeatureItem[] = []

    modules.forEach((moduleName) => {
      const featureId = this.getFeatureIdValueForModule(moduleName)
      const configEnabled = this.isFeatureSupported(HOSTNAME, featureId)

      const isAdEngine = featureId === AppModule.AdEngine.id
      let isSupported = configEnabled

      // 显示净化面板特殊处理：如果检测到隐藏规则，认为支持；否则不支持
      if (isAdEngine)
        isSupported = detectElementHideRules()

      if (isAdEngine && !configEnabled) {
        loggerDeduplicator.warn(`[${this.name}] 检测到隐藏规则，默认开启显示净化面板（请检查元素配置）`)
      }
      else if (isAdEngine && configEnabled && !isSupported) {
        loggerDeduplicator.info(`[${this.name}] ${SYMBOLS.STATUS.WARNING} 未检测到隐藏规则，默认关闭显示净化面板`)
      }

      if (featureId && isSupported) {
        const config = this.getEnhancedFeatureConfig(HOSTNAME, featureId)

        if (config)
          supportedModules.push(config)
      }
    })

    return supportedModules
  }

  /**
   * 注册功能处理函数
   * @param featureId 功能 ID
   * @param handler 处理函数
   */
  registerHandler(featureId: ModuleId, handler: FeatureHandler): void {
    this.featureHandlers.set(featureId, handler)
  }

  /**
   * 更新功能启用状态
   * @param featureId 功能 ID
   * @param enabled 是否启用
   * @param options 选项
   */
  async setFeatureEnabled(
    featureId: ModuleId,
    enabled: boolean,
    options?: SetFeatureEnabledOptions,
  ): Promise<void> {
    const { effectType = EffectType.IMMEDIATE, first = false, temporary = false } = options || {}

    if (!temporary)
      // 保存到缓存
      this.storage.set(`${this.getStoragePrefix(featureId)}${featureId}`, enabled, this.storageOptions)

    const enabledEmoji = enabled ? SYMBOLS.NETWORK.UNLOCK : SYMBOLS.NETWORK.LOCK
    const saveStatusEmoji = effectType ? SYMBOLS.UI.SAVE : SYMBOLS.STATUS.REFRESH

    logger.info(`[${this.name}] ${enabledEmoji} ${saveStatusEmoji} feature '${featureId}'`)

    if (!effectType)
      return

    if (!featureId)
      return

    // 执行对应的处理函数
    const handler = this.featureHandlers.get(featureId)

    if (handler) {
      try {
        await handler(enabled, first)
      }
      catch (err: any) {
        logger.error(`[${this.name}] [${featureId}] 执行功能处理函数失败`, err)
      }
    }
    else {
      logger.warn(`[${this.name}] [${featureId}] 未注册处理函数`)
    }
  }

  /**
   * 获取存储前缀
   */
  getStoragePrefix(featureId: ModuleId): string {
    const usePageTypeIsolation = this.getFeatureDefaultUsePageTypeIsolation(featureId)
    return usePageTypeIsolation ? `${this.featureStoragePrefix}@${this.pageType}:` : this.featureStoragePrefix
  }

  /**
   * 获取功能当前启用状态
   * @param featureId 功能 ID
   * @param defaultValue 默认值
   */
  getFeatureEnabled(featureId: ModuleId, defaultValue?: boolean): boolean {
    return this.storage.get(`${this.getStoragePrefix(featureId)}${featureId}`, defaultValue ?? this.getFeatureDefaultEnabled(featureId), this.storageOptions)
  }

  /**
   * 获取功能默认启用状态
   * @param featureId 功能 ID
   */
  getFeatureDefaultEnabled(featureId: ModuleId): boolean {
    const config = this.getFeatureConfig(HOSTNAME, featureId)
    return config?.defaultEnabled ?? false
  }

  /**
   * 获取功能默认使用页面类型隔离状态
   * @param featureId 功能 ID
   */
  getFeatureDefaultUsePageTypeIsolation(featureId: ModuleId): boolean {
    const config = this.getFeatureConfig(HOSTNAME, featureId)
    return config?.usePageTypeIsolation ?? false
  }

  /**
   * 重置所有功能配置
   */
  resetAllFeatures(): void {
    // 清除所有功能状态缓存
    this.featureHandlers.forEach((_, featureId) => {
      this.storage.delete(`${this.getStoragePrefix(featureId)}${featureId}`)
    })

    // 重置配置
    this.storage.delete('config')
    this.loadConfig()
  }

  applyConfig(_sconfig: Partial<Config>): void {
  }

  /**
   * 自动绑定模块与配置管理器
   * @param moduleManager 模块管理器实例
   */
  autoRegisterModules(moduleManager: ModuleManager): void {
    // 自动注册所有模块
    Object.values(AppModule).forEach((meta) => {
      const moduleName = meta.className
      const featureId = meta.id
      const module = moduleManager.getModule(moduleName)

      // 仅绑定已注册的模块
      if (module) {
        this.registerHandler(featureId, async (enabled: boolean, first: boolean) => {
          const result = module.onToggleCallback(featureId, enabled, first)

          if (ToolKit.func.isPromise(result))
            await result
        })
        logger.debug(`[${this.name}] Bound module ${moduleName} to ID ${featureId}`)
      }
    })
  }
}
